<?php
namespace wow\controller;

use \wow\model\dbcon as dbs;

use \wow\modelauth as auth;
use \wow\modelchar as chr;
use \wow\modelworld as wrd;
use \gnomephp\message\Message;
use \gnomephp\doctrine\Doctrine;
class Admin extends BaseController{

	
	
	public function forum($action = null, $id = null){
		if (!$this->hasPermissionTo('admin_panel')){
			$this->redirect($this->view->url->linkTo('Auth','login'));
		}
		
		$forum = null;
		
		if ($id){
			$forum = \wow\model\forum\Forum::getForumById($id);
			$this->view->assign('forum', $forum);
		}
		
		switch($action){
			case 'delete':
				\wow\model\forum\Forum::deleteForumById($id);
				Message::add(Message::SUCCESS, "Deleted forum {$forum->getTitle()}");
				$this->redirect($this->view->url->linkTo('Admin','forum'));
				break;
			case 'add':
			case 'edit':
				$args = $id ? array($action, $id) : array($action);
				
				$form = $this->view->createForm('forumForm', $this->view->url->linkTo('Admin','forum', $args), 'post',
				function (\gnomephp\input\Input $input) use ($forum){
						
					try{
						$title = (string)$input->post->get('title')->required()->validate('Title');
						$description = (string)$input->post->get('description')->validate('Description');
						$accessLevel = (string)$input->post->get('accessLevel')->numeric()->validate('Access Level');
						$accessLevelThread = (string)$input->post->get('accessLevelThread')->numeric()->validate('Access Level to create threads');
						$accessLevelReply = (string)$input->post->get('accessLevelReply')->numeric()->validate('Access Level to reply to threads');
						$url = (string)$input->post->get('url')->validate('Url');
						if (!$url)$url = null;
						
						
						$update = false;
						if ($forum){
							$update = true;
							$forum->setTitle($title);
							$forum->setAccess($accessLevel);
							$forum->setDescription($description);
							$forum->setUrl($url === null ? $title : $url);
						}else{
							$forum = new \wow\model\forum\Forum($title, $url, $description, $accessLevel);
				
						}
						$forum->setThreadAccess((int)$accessLevelThread);
						$forum->setReplyAccess((int)$accessLevelReply);
						
						
						Doctrine::load();
						Doctrine::getEM()->persist($forum);
						Doctrine::getEM()->flush();
							
							
							
						Message::add(Message::SUCCESS, ($update ? 'Updated' : 'Added') ." forum {$forum->getTitle()}.");
							
					}catch(\gnomephp\input\DataFieldValidException $e){
						Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
					}
				}
				
				);
				$this->view->assign('forumForm', $form);
				$this->view->render('admin/forum/form');
				break;
			default:
				$this->view->assign('forums', \wow\model\forum\Forum::getAllForums());
				
				$this->view->render('admin/forum/forum');
		}
		
		
	}
	
	
	public function donation($action=null, $id = null){
		if (!$this->hasPermissionTo('admin_realm')){
			Message::add(Message::ERROR, 'You have no access to this function.');
			$this->redirect($this->view->url->linkTo('Admin','index'));
		}
		$don = null;
		if ($id){
			$don = \wow\model\Donation::getDonation($id);
			$this->view->assign('don', $don);
		}
		
		switch($action){
			
			case 'orders':
				
				$orders = \wow\model\PayPalOrder::getOrders();
				
				$this->view->assign('orders', $orders);
				$this->view->render('admin/donation/orders');
				
				break;
			
			
			case 'delete':
				Doctrine::load();
				$q = Doctrine::getEM()->createQuery("DELETE FROM wow\model\Donation d WHERE d.itemid = ?1")
				->setParameter(1, $id);
				$q->execute();
				Message::add(Message::SUCCESS, "Deleted donation item {$don->getName()}.");
				$this->redirect($this->view->url->linkTo('Admin','donation'));
				break;
			
			case 'add':
			case 'edit':
				$args = $id ? array($action, $id) : array($action);
				
				$form = $this->view->createForm('realmForm', $this->view->url->linkTo('Admin','donation', $args), 'post',
				function (\gnomephp\input\Input $input) use ($don){
					
					try{
					$name = (string)$input->post->get('name')->required()->validate('Name');
					$message = (string)$input->post->get('message')->required()->validate('Package info');
					$price = (string)$input->post->get('price')->required()->numeric()->validate('Price');
					$currency = (string)$input->post->get('currency')->required()->validate('Currency');
					$itemsGive = (string)$input->post->get('itemsGive');
					$moneyGive = (string)$input->post->get('moneyGive');
					
					
					$update = false;
					if ($don){
						$update = true;
						$don->setName($name);
						$don->setMessage($message);
						$don->setCurrency($currency);
						$don->setPrice($price);
					}else{
						$don = new \wow\model\Donation($name, $message, $price, $currency);
						
					}
					
					// Get all realms
					$realms = \wow\modelauth\Realmlist::getAllRealms();
					
					$don->setMoney($moneyGive);
					$unexsistedItems = $don->setItems($itemsGive, $realms[0]->id);
					
					
					Doctrine::load();
					Doctrine::getEM()->persist($don);
					Doctrine::getEM()->flush();
					
					
					
					Message::add(Message::SUCCESS, ($update ? 'Updated' : 'Added') ." donation item.");
					
					if ($unexsistedItems){
						Message::add(Message::WARNING, 'Some items was not added because they did not exist in db, here are the ids:<br />'.implode('<br />', $unexsistedItems));
					}
					
					}catch(\gnomephp\input\DataFieldValidException $e){
						Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
					}
				}
				
				);
				$this->view->assign('donForm', $form);
				$this->view->render('admin/donation/form');
				break;
			default:
				
				$this->view->assign('donations', \wow\model\Donation::getDonations());
				
				$this->view->render('admin/donation/donation');
				
				break;
		}
	}
	
	

	/**
	 * Should be run by ajax request.
	 * 
	 * Runs command against the soap interface.
	 * @param unknown_type $realmId
	 */
	public function runcommand(){
		$realmId = (string)$this->input->post->get('id');
		$command = (string)$this->input->post->get('c');
		

		$com = \wow\model\Soap::generateSoapFactory($realmId, $this->user);
		
		if ($com != null){
			$args =(array)(isset($this->input->post) ? $this->input->post->get('args') : array() );
			foreach($args as $k => $v){
				$args[$k] = (string)$v;
			}
			try{
				echo call_user_func_array(array($com, $command), $args);
			}catch(\Exception $e){
				die($e->getMessage());
			}
		}else{
			echo "Soap not enabled in configuration.";
		}
		
		die();
		
	}

	public function realm_command($realmId){
		if (!$this->hasPermissionTo('admin_realm')){
			Message::add(Message::ERROR, 'You have no access to this function.');
			$this->redirect($this->view->url->linkTo('Admin','index'));
		}
		$com = \wow\model\Soap::generateSoapFactory($realmId, $this->user);
		
		if (!$com){
			$this->view->assign('soapEnabled', false);
		}else{
			$this->view->assign('soapEnabled', true);
		}
		
		$form = $this->view->createForm('cmdform', $this->view->url->linkTo('Admin','runcommand'), 'post');
		
		$this->view->assign('f', $form);
		
		$realm = auth\Realmlist::getRealmById($realmId);
		$this->view->assignGlobal('realm', $realm);
		$this->view->render('admin/realm_command');
		
	}

	public function index(){
		if (!$this->hasPermissionTo('admin_panel')){
			$this->redirect($this->view->url->linkTo('Auth','login'));
		}
		$this->view->render('admin/index');
	}

	public function realm($id){
		if (!$this->hasPermissionTo('admin_realm')){
			Message::add(Message::ERROR, 'You have no access to this function.');
			$this->redirect($this->view->url->linkTo('Admin','index'));
		}

		$realm = auth\Realmlist::getRealmById($id);


		$controller = $this;
		$form = $this->view->createForm('realmForm', $this->view->url->linkTo('Admin','realm', array($id)), 'post',
		function(\gnomephp\input\Input $input) use($controller, $realm){
			$port = (string)$input->post->get('port');
			$host = (string)$input->post->get('host');
			$name = (string)$input->post->get('name');

			$realm->address = $host;
			$realm->port = $port;
			$realm->name = $name;
				
			dbs\AuthDB::load();
			dbs\AuthDB::getEM()->persist($realm);
			dbs\AuthDB::getEM()->flush();
				
			Message::add(Message::SUCCESS, 'Updated realm info.');
		}
		);
		$this->view->assign('realmForm', $form);
		$this->view->assign('realm', $realm);
		$this->view->render('admin/realm');
	}
	
	
	public function startitems($id, $classId = null){
		if (!$this->hasPermissionTo('admin_realm')){
			Message::add(Message::ERROR, 'You have no access to this function.');
			$this->redirect($this->view->url->linkTo('Admin','index'));
		}
		
		// Ajax call.
		if ($classId !== null){
			echo wrd\PlayerCreateItem::parseItemsToCode($id, $classId);
			die();
		}
		
		$realm = auth\Realmlist::getRealmById($id);
		
		
		$controller = $this;
		$form = $this->view->createForm('startForm', $this->view->url->linkTo('Admin','startitems', array($id)), 'post',
		function(\gnomephp\input\Input $input) use($controller, $realm){
			$class = (string)$input->post->get('class');
			$itemamount = (string)$input->post->get('itemamount');
			
			$items = wrd\PlayerCreateItem::parseItemsFromCode($itemamount);
			
			wrd\PlayerCreateItem::updateItemsForClass($realm->id, $class, $items, true);
			Message::add(Message::SUCCESS, 'Updated items for class.');
		}
		);
		$this->view->assign('startForm', $form);		
		
		$this->view->assign('classes', chr\Character::getClasses());
		$this->view->assignGlobal('realm', $realm);
		
		$this->view->render('admin/startitems');
		
	}
	
	public function commands($id){
		if (!$this->hasPermissionTo('admin_realm')){
			Message::add(Message::ERROR, 'You have no access to this function.');
			$this->redirect($this->view->url->linkTo('Admin','index'));
		}
		
		$realm = auth\Realmlist::getRealmById($id);
		
		
		$this->view->assign('commands', $realm->getCommands($this->user->getGmLevel()));
		$this->view->assignGlobal('realm', $realm);
		
		$this->view->render('admin/commands');
		
	}
	


	public function news($task = null, $id = null){
		if (!$this->hasPermissionTo('news_admin')){
			Message::add(Message::ERROR, 'You have no access to this function.');
			$this->redirect($this->view->url->linkTo('Admin','index'));
		}
		if ($id){
			$news = \wow\model\News::getNewsitem($id);
		}else{
			$news = null;
		}
		$this->view->assign('news', $news);


		switch($task){
			case 'add':
			case 'edit':

				
				$controller = $this;
				$user = $this->user;
				$args = $task == 'edit' ? array($task,$id) : array($task);
				$form = $this->view->createForm('newsForm', $this->view->url->linkTo('Admin','news', $args), 'post',
				function(\gnomephp\input\Input $input) use($controller, $news, $user){
					$title = (string)$input->post->get('title');
					$body = (string)$input->post->get('body');
					$acceptComment = (string)$input->post->get('acceptComment');
					$announceOnRealms = (bool)((string)$input->post->get('announceOnRealms'));

					if (!$news){
						$news = new \wow\model\News($title, $body);
					}else{
						$news->setTitle($title);
						$news->setText($body);
					}
					
					$news->setCommentsEnabled($acceptComment);
					$news->setAccountId($user->getID());
					
					Doctrine::load();
					Doctrine::getEM()->persist($news);
					Doctrine::getEM()->flush();
					
					if ($announceOnRealms){
						$realms = auth\Realmlist::getAllRealms();
						foreach($realms as $realm){
							$com = \wow\model\Soap::generateSoapFactory($realm->id, $controller->user);
							if ($com){
								$com->announce($title);
							}
						}
					}
					
						
					Message::add(Message::SUCCESS, 'News saved');
					
					$controller->redirect($controller->view->url->linkTo('News', 'view', array('id' => $news->getID() , 'title' => $news->getUrl())));
				}
				);
				$this->view->assign('newsForm', $form);

				
				
				$this->view->render('admin/news_cu');
				break;
			case 'delete':
				if ($id)\wow\model\News::deleteNewsitem($id);
				Message::add(Message::SUCCESS, 'Deleted news article!');
				$this->redirect($this->view->url->linkTo('Admin','news'));
				break;
			default:
				$news = \wow\model\News::getNews(40, 0);
				$this->view->assign('news', $news);
				$this->view->render('admin/news_r');
				break;
		}
	}

	public function accounts($username=null){
		if (!$this->hasPermissionTo('admin_accounts')){
			Message::add(Message::ERROR, 'You have no access to this function.');
			$this->redirect($this->view->url->linkTo('Admin','index'));
		}
		$search_acc = null;
		if ($username)$search_acc = auth\Account::getUserByUsername($username);

		$controller = $this;
		$form = $this->view->createForm('searchChar', $this->view->url->linkTo('Admin','accounts'), 'post',
		function(\gnomephp\input\Input $input) use($controller, $search_acc){
			$name = (string)$input->post->get('search');
			$search_acc = auth\Account::getUserByUsername($name);

			if (!$search_acc){
				Message::add(Message::ERROR, 'Found no users for the search.');
			}else{
				$controller->redirect($controller->view->url->linkTo('Admin','accounts').'/'.$name);
			}
		}
		);


		$this->view->assign('searchForm', $form);

		if ($search_acc){
			$this->view->assign('searchAcc', $search_acc);
				
				
			$form = $this->view->createForm('accForm', $this->view->url->linkTo('Admin','accounts') . '/' . $search_acc->getUsername(), 'post',
			function(\gnomephp\input\Input $input) use($controller, $search_acc){
				$uid = (string)$input->post->get('uid');
				$acc = $search_acc;
					
				try{


					$username = (string)$input->post->get('username');
					$gmlevel = (string)$input->post->get('gmlevel');

					$password = (string)$input->post->get('password');
					if ($password)$input->post->get('password2', 'Confirm password')->matches($password, 'Password')->validate();

					$email = (string)$input->post->get('email');
					$locked = (string)$input->post->get('locked');
						
						
					dbs\AuthDB::load();
					

					$acc->setGmLevel((int)$gmlevel);
					$acc->setEmail($email);
					$acc->setLocked($locked);
					if ($password)$acc->setPassword($username, $password);
					$acc->setUsername($username);

						
					dbs\AuthDB::getEM()->persist($acc);
					dbs\AuthDB::getEM()->flush();




					Message::add(Message::SUCCESS, 'Saved account ' . $username);



				}catch(\gnomephp\input\DataFieldValidException $e){
					Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
				}

			}
			);

			$this->view->assign('accForm', $form);

			$form = $this->view->createForm('banAcc', $this->view->url->linkTo('Admin','accounts') . '/' . $search_acc->getUsername(), 'post',
			function(\gnomephp\input\Input $input) use($controller, $search_acc){
				$unban = (string)$input->post->get('unbandate');
				$userid = (string)$input->post->get('uid')->required()->validate();
				$reason = (string)$input->post->get('reason')->required()->validate();
					
				$ban = new auth\AccountBan($userid, $controller->user->getUsername(), $reason);
					
				if ((string)$input->post->get('permaban') == '0'){
					$ban->setUnbanDateInMS($unban);
				}
					
				dbs\AuthDB::load();
				dbs\AuthDB::getEM()->persist($ban);
					
				dbs\AuthDB::getEM()->flush();
					
				Message::add(Message::SUCCESS, 'User banned.');
			}
			);
			$this->view->assign('banForm', $form);

			$userBans = auth\AccountBan::getActiveBansForUserId($search_acc->getID());
			$this->view->assign('userBans', $userBans);
		}





		$this->view->render('admin/accounts');
	}
}